package com.eling.elcms.travel.service.impl;

import com.eling.elcms.basedoc.model.BusinessMessage;
import com.eling.elcms.basedoc.model.Room;
import com.eling.elcms.basedoc.model.Room.Status;
import com.eling.elcms.basedoc.model.TargetType;
import com.eling.elcms.basedoc.model.TaskType;
import com.eling.elcms.basedoc.service.IBusinessMessageManager;
import com.eling.elcms.basedoc.service.IRoomManager;
import com.eling.elcms.core.AppContext;
import com.eling.elcms.core.service.impl.GenericManagerImpl;
import com.eling.elcms.core.util.PropertyUtils;
import com.eling.elcms.system.model.CommonUser;
import com.eling.elcms.system.service.impl.CommonUserManagerImpl;
import com.eling.elcms.travel.dao.IRoomRegisterDao;
import com.eling.elcms.travel.model.CheckIn;
import com.eling.elcms.travel.model.CheckInImplement;
import com.eling.elcms.travel.model.CheckInImplement.CheckStatus;
import com.eling.elcms.travel.model.RoomPersonalInfo;
import com.eling.elcms.travel.model.RoomRegister;
import com.eling.elcms.travel.model.view.RoomRegisterListView;
import com.eling.elcms.travel.model.view.RoomStatusView;
import com.eling.elcms.travel.model.view.RoomView;
import com.eling.elcms.travel.service.*;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class RoomRegisterManagerImpl extends GenericManagerImpl<RoomRegister, Long> implements IRoomRegisterManager{

	IRoomRegisterDao roomRegisterDao;
	
	@Autowired
	private CommonUserManagerImpl commonUserManagerImpl;
	@Autowired
	private IRoomManager roomManager;
	@Autowired
	private IRoomPersonalInfoManager roomPersonM;
	@Autowired
	private ICheckInImplementManager cIImplementM;
	@Autowired
	private ICheckInManager checkInManager;
	@Autowired
	private IRoomOccupancyManager roomOccupancyManager;
	@Autowired
	private ICheckInImplementManager CheckInImplementM;
	@Autowired
	private IBusinessMessageManager businessMessageManager;

	@Autowired
	public void setRoomRegisterDao(IRoomRegisterDao roomRegisterDao) {
		this.dao = roomRegisterDao;
		this.roomRegisterDao = roomRegisterDao;
	}

	@Override
	public RoomRegister confirm(RoomRegister roomRegister){
		roomRegister = save(roomRegister);
		
		// 回写入住准备落实单房间落实状态
		// 查到房间登记对应的人员入住信息
		RoomPersonalInfo cond = new RoomPersonalInfo();
		cond.setRoomRegister(roomRegister);
		List<RoomPersonalInfo> infoList = roomPersonM.query(cond);
		if (infoList != null && infoList.size() > 0){
			CheckInImplement cii = infoList.get(0).getCheckInImplement();
			if (cii.getRoomStatus() != CheckStatus.Pended){
				// 根据房间入住信息中的入住准备落实单获取到所有的房间入住信息
				RoomPersonalInfo newInfoCond = new RoomPersonalInfo();
				newInfoCond.setCheckInImplement(infoList.get(0).getCheckInImplement());
				List<RoomPersonalInfo> infoListAll = roomPersonM.query(newInfoCond);
				// 判断所有的房间是否均已经落实完毕
				boolean flag = true;
				for(RoomPersonalInfo in : infoListAll){
					if (in.getRoomRegister().getStatus() == null
							|| in.getRoomRegister().getStatus() != CheckStatus.Pended){
						flag = false;
						break;
					}else{
						//
					}
				}		
				if (flag){
					cii.setRoomStatus(CheckStatus.Pended);
					cii = cIImplementM.save(cii);
					// 设置入住准备落实单总表的已落实状态
					cIImplementM.setCiiCheckStatusConfirm(cii);
				}
			}
		}
		
		return roomRegister;
	}

	@Override
	public List<RoomRegister> queryMeter(Long pkCheckInImplement) {
		CheckInImplement checkInImplement = CheckInImplementM.get(pkCheckInImplement);
		//DataSource dataSource = checkInImplement.getDataSource();
		//return roomRegisterDao.queryMeter(pkCheckInImplement,dataSource);
		return roomRegisterDao.queryMeter(checkInImplement);
	}

	@Override
	public RoomRegister saveMeter(RoomRegister cond) {
		RoomRegister room = get(cond.getPkRoomRegister());
		RoomRegister roomRegister = new RoomRegister();
		roomRegister.setRoomStatus(room.getRoomStatus());
		roomRegister.setRoom(room.getRoom());
		List<RoomRegister> registers = query(roomRegister);
		
		Boolean sendFlag = false;
		for (RoomRegister register : registers) {
			if(cond.getRoomStatus().name().equals(com.eling.elcms.travel.model.RoomRegister.RoomStatus.NoCheckIn.name())){
				register.setWaterMeter(cond.getWaterMeter());
				register.setElectricMeter(cond.getElectricMeter());
				register.setHotWaterMeter(cond.getHotWaterMeter());
				register.setRoomStatus(RoomRegister.RoomStatus.CheckIn);
				register.setCheckInMeterDate(cond.getCheckInMeterDate());
				roomRegister = save(register);
			}else{
				register.setCheckOutWaterMeter(cond.getCheckOutWaterMeter());
				register.setCheckOutElectricMeter(cond.getCheckOutElectricMeter());
				register.setCheckOutHotWaterMeter(cond.getCheckOutHotWaterMeter());
				register.setRoomStatus(RoomRegister.RoomStatus.finish);
				register.setCheckOutMeterDate(cond.getCheckOutMeterDate());
				roomRegister = save(register);
				sendFlag = true;
			}
		}
		if(sendFlag){
			businessMessageManager.saveBusinessMessage(new BusinessMessage(TargetType.Role,TaskType.CheckOut,999L));
		}
		return roomRegister;
	}

	@Override
	public RoomRegister updateStatus(Long pkCheckInImplement) {
		CheckInImplement checkInImplement = cIImplementM.get(pkCheckInImplement);
		List<RoomPersonalInfo> rpiList = new ArrayList<>(checkInImplement.getRoomPersonalInfos());
		
		if(!rpiList.isEmpty()){
			// 获取所有房间登记修改状态
			List<RoomRegister> rrList = rpiList.stream().map(a->a.getRoomRegister()).collect(Collectors.toList());
			if(!rrList.isEmpty()){
				for(RoomRegister rr : rrList){
					if(rr.getStatus().equals(CheckStatus.Pending)){
						rr.setCardKey(true);
						rr.setWater(true);
						rr.setElectric(true);
						rr.setGas(true);
						rr.setTelephone(true);
						rr.setWireless(true);
						rr.setStatus(CheckStatus.Pended);
					}
				}
				rrList = save(rrList);
			}
		}
		//修改主表房间落实状态为已落实
		checkInImplement.setRoomStatus(CheckStatus.Pended);
		checkInImplement = cIImplementM.save(checkInImplement);
		
		//修改主表总状态为已落实
		cIImplementM.setCiiCheckStatusConfirm(checkInImplement);
		
		return new RoomRegister();
	}

	@Override
	public List<Room> queryRoomByStatus(Room cond) {
		return roomManager.query(cond);
	}
	
	private List<Room> queryRoomByWillGo(){
		CheckInImplement checkInImplement = new CheckInImplement();
		SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
		Calendar now = Calendar.getInstance(); 
		String str = now.get(Calendar.YEAR)+"-"+(now.get(Calendar.MONTH) + 1)+"-"+(now.get(Calendar.DAY_OF_MONTH))+" 00:00:00"; 
		String str1 = now.get(Calendar.YEAR)+"-"+(now.get(Calendar.MONTH) + 1)+"-"+(now.get(Calendar.DAY_OF_MONTH))+" 23:59:59"; 
		Date dates =new Date();
		Date dates1 =new Date();
		try {
			dates = sdf.parse(str);
			dates1 = sdf.parse(str1);
		} catch (ParseException e) {
			e.printStackTrace();
		}
		PropertyUtils.setProperty(checkInImplement, "groupReserve.checkOutDate", dates);
		PropertyUtils.setProperty(checkInImplement, "groupReserve.checkOutDateEnd", dates1);
		List<CheckInImplement> ciiList = cIImplementM.query(checkInImplement);
		PropertyUtils.setProperty(checkInImplement, "groupReserve", null);
		PropertyUtils.setProperty(checkInImplement, "nonMemGroupReserve.nonMemberGroup.checkOutDate", dates);
		PropertyUtils.setProperty(checkInImplement, "nonMemGroupReserve.nonMemberGroup.checkOutDateEnd", dates1);
		List<CheckInImplement> ciiListOne = cIImplementM.query(checkInImplement);
		ciiList.addAll(ciiListOne);
		if(!ciiList.isEmpty()){
			List<RoomPersonalInfo> rmPerInfoList = new ArrayList<>();
			for(CheckInImplement cii : ciiList){
				rmPerInfoList.addAll(cii.getRoomPersonalInfos());
			}
			if(!rmPerInfoList.isEmpty()){
				List<Room> rmListOne = new ArrayList<>(); 
				for(RoomPersonalInfo rmPerInfo : rmPerInfoList){
					if(null != rmPerInfo.getRoomRegister().getRoom()){
						rmListOne.add(rmPerInfo.getRoomRegister().getRoom());
					}
				}
				Set<Room> rmSet = new HashSet<>(rmListOne);
				if(!rmSet.isEmpty()){
					List<Room> rmList = new ArrayList<>(rmSet);
					return rmList;
				}
			}
		}
		return null;
	}

	@Override
	public List<RoomStatusView> queryRoomStatus(Room cond, Date startDate, Date endDate) {
		List<Room> list = queryRoomByStatus(cond);
		List<Long> pklist = new ArrayList<Long>();
		for(Room room : list){
			if(room.getStatus() !=null && room.getStatus().equals(Status.CheckIn)){
				pklist.add(room.getPkRoom());
			}
		}
		CheckIn checkin = new CheckIn();
		PropertyUtils.setProperty(checkin, "checkInDate", startDate);
		PropertyUtils.setProperty(checkin, "checkInDateEnd", endDate);
		PropertyUtils.setProperty(checkin, "roomRegister.room.pkRoomIn", pklist);
		List<CheckIn> checkInList = checkInManager.query(checkin);
		List<RoomStatusView> viewList = new ArrayList<RoomStatusView>();
		
		List<Room> willGoList = queryRoomByWillGo();
		
		for(Room room : list){
			RoomStatusView view = new RoomStatusView();
			view.setRoom(room);
			for(CheckIn c : checkInList){
				if(room.getPkRoom().equals(c.getRoomRegister().getRoom().getPkRoom())){
					view.setCheckOutDate(c.getCheckOutDate());
				}
			}
			if(willGoList!=null && willGoList.size()>0){
				for(Room willGoRoom:willGoList){
					if(room.getPkRoom().equals(willGoRoom.getPkRoom())){
						view.setIsWillGo(true);
					}
				}
			}
			viewList.add(view);
		}
		
		return viewList;
	}
	
	/**
	 * 入住登记新增
	 */
	public RoomRegisterListView saveNewRoomRegister(RoomRegisterListView cond){
		List<RoomRegister> roomRegisterList = new ArrayList<RoomRegister>();
		
		for(RoomRegister roomRegister:cond.getRoomRegisterList()){
			Room room = roomRegister.getRoom();
			room = roomManager.get(room.getPkRoom());
			room.setStatus(Status.CheckIn);
			roomRegister = this.dao.get(roomRegister.getPkRoomRegister());			
			roomRegister.setRoom(room);
			roomRegisterList.add(roomRegister);
		}
		this.dao.save(roomRegisterList);
		return cond;
	}

	@Override
	public Long queryPk(Long pkRoomPersonalInfo) {
		return roomRegisterDao.queryPk(pkRoomPersonalInfo);
	}

	@Override
	public List<RoomRegisterListView> printRoom(Long pkServicePoint) {
		Long pkUser = AppContext.curUser().getPkUser();
		CommonUser commonUser = commonUserManagerImpl.get(pkUser);
		pkServicePoint = commonUser.getServicePoint().getPkServicePoint();
		return roomRegisterDao.printRoom(pkServicePoint);
	}

	@Override
	public RoomView queryByPkRoom(Long pkRoom) {
		return roomRegisterDao.queryByPkRoom(pkRoom);
	}
	
}
